home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pine / pine3.07 / pico / tinfo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-16  |  12.3 KB  |  613 lines

  1. /*
  2.  * Program:    Display routines
  3.  *
  4.  * Modifier:    Donn Cave
  5.  *        University Computing Services
  6.  *        University of Washington
  7.  *        Seattle, WA  98195
  8.  *        Internet: donn@cac.washington.edu
  9.  *
  10.  * Date:    15 April 1992
  11.  * Last Edited:    15 April 1992
  12.  *
  13.  * Copyright 1991 by the University of Washington
  14.  *
  15.  *  Permission to use, copy, modify, and distribute this software and its
  16.  * documentation for any purpose and without fee is hereby granted, provided
  17.  * that the above copyright notice appears in all copies and that both the
  18.  * above copyright notice and this permission notice appear in supporting
  19.  * documentation, and that the name of the University of Washington not be
  20.  * used in advertising or publicity pertaining to distribution of the software
  21.  * without specific, written prior permission.  This software is made
  22.  * available "as is", and
  23.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  24.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  25.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  26.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  27.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  28.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  29.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  30.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  31.  *
  32.  */
  33. /*
  34.     tinfo - substitute for tcap, on systems that have terminfo.
  35. */
  36.  
  37. #define    termdef    1            /* don't define "term" external */
  38.  
  39. #include    <stdio.h>
  40. #include    <sys/ioctl.h>
  41. #include    <termios.h>
  42. #define NOMACROS
  43. #define timeout curses_timeout
  44. #include    <curses.h>
  45. #define WINDOW our_WINDOW
  46. #undef timeout
  47. #undef NOMACROS
  48. #include    <term.h>
  49. #include        <signal.h>
  50. #include    "osdep.h"
  51. #include    "estruct.h"
  52. #include        "edef.h"
  53. #include        "pico.h"
  54.  
  55. extern char *tigetstr ();
  56.  
  57. #define NROW    24
  58. #define NCOL    80
  59. #define    MARGIN    8
  60. #define    SCRSIZ    64
  61. #define BEL     0x07
  62. #define ESC     0x1B
  63.  
  64. extern int      ttopen();
  65. extern int      ttgetc();
  66. extern int      ttputc();
  67. extern int      ttflush();
  68. extern int      ttclose();
  69.  
  70. static int      tinfomove();
  71. static int      tinfoeeol();
  72. static int      tinfoeeop();
  73. static int      tinfobeep();
  74. static int    tinforev();
  75. static int      tinfoopen();
  76.  
  77. extern int      tput();
  78. extern char     *tgoto();
  79.  
  80. static char *UP, PC, *CM, *CE, *CL, *SO, *SE;
  81. /* 
  82.  * PICO extentions 
  83.  */
  84. static char *DL,            /* delete line */
  85.     *AL,            /* insert line */
  86.     *CS,            /* define a scrolling region, vt100 */
  87.     *IC,            /* insert character, preferable to : */
  88.     *IM,            /* set insert mode and, */
  89.     *EI,            /* end insert mode */
  90.     *DC,            /* delete character */
  91.     *DM,            /* set delete mode and, */
  92.     *ED,            /* end delete mode */
  93.     *SF,            /* scroll text up */
  94.     *SR;            /* scroll text down */
  95.  
  96. static char *KU, *KD, *KL, *KR;
  97. static char *KPPU, *KPPD, *KPHOME, *KPEND;
  98.  
  99. struct KBSTREE *kpadseqs = NULL;
  100.  
  101. TERM term = {
  102.         NROW-1,
  103.         NCOL,
  104.     MARGIN,
  105.     SCRSIZ,
  106.         tinfoopen,
  107.         ttclose,
  108.         ttgetc,
  109.         ttputc,
  110.         ttflush,
  111.         tinfomove,
  112.         tinfoeeol,
  113.         tinfoeeop,
  114.         tinfobeep,
  115.         tinforev
  116. };
  117.  
  118.  
  119. static tinfoopen()
  120. {
  121.     char  *t, *p;
  122.     char  *tv_stype;
  123.     char  *initstrng = "";
  124.     char   err_str[72];
  125.     char  *getenv();
  126.     struct termios tty;
  127.  
  128. #ifdef TIOCGWINSZ
  129.     struct winsize win;
  130.     if (ioctl(0, TIOCGWINSZ, &win) == 0) {
  131.     term.t_ncol = (win.ws_col) ? win.ws_col : 80;
  132.     term.t_nrow = (win.ws_row) ? win.ws_row - 1 : 23;
  133.     }
  134. #endif
  135.  
  136.     /*
  137.      * determine the terminal's communication speed and decide
  138.      * if we need to do optimization ...
  139.      */
  140.     if (tcgetattr (1, &tty) == 0) {
  141.     if(cfgetospeed (&tty) < B9600)
  142.       optimize = TRUE;
  143.     }
  144.  
  145.     if (Pmaster) {
  146.     /*
  147.      *        setupterm() automatically retrieves the value
  148.      *        of the TERM variable.
  149.      */
  150.     int err;
  151.     setupterm (0, 1, &err);
  152.     if (err != 1) return FALSE;
  153.     }
  154.     else {
  155.     /*
  156.      *        setupterm() issues a message and exits, if the
  157.      *        terminfo data base is gone or the term type is
  158.      *        unknown, if arg2 is 0.
  159.      */
  160.     setupterm (0, 1, 0);
  161.     }
  162.  
  163.     t = tigetstr("pad");
  164.     if(t)
  165.       PC = *t;
  166.  
  167.     CL = tigetstr("clear");
  168.     CM = tigetstr("cup");
  169.     CE = tigetstr("el");
  170.     UP = tigetstr("cuu1");
  171.     SE = tigetstr("rmso");
  172.     SO = tigetstr("smso");
  173.     if (SO != NULL)
  174.       revexist = TRUE;
  175.  
  176.     DL = tigetstr("dl1");
  177.     AL = tigetstr("il1");
  178.     CS = tigetstr("csr");
  179.     IC = tigetstr("ich1");
  180.     IM = tigetstr("smir");
  181.     EI = tigetstr("rmir");
  182.     DC = tigetstr("dch1");
  183.     DM = tigetstr("smdc");
  184.     ED = tigetstr("rmdc");
  185.     SF = tigetstr("ind");
  186.     SR = tigetstr("ri");
  187.     if(DC == NULL && (DM == NULL || ED == NULL))
  188.       delchar = FALSE;
  189.     if(IC == NULL && (IM == NULL || EI == NULL))
  190.       inschar = FALSE;
  191.     if((CS==NULL || SF==NULL || SR==NULL) && (DL==NULL || AL==NULL))
  192.       scrollexist = FALSE;
  193.  
  194.     if(CL == NULL || CM == NULL || UP == NULL){
  195.     if(Pmaster == NULL){
  196.         puts("Incomplete terminfo entry\n");
  197.         exit(1);
  198.     }
  199.     }
  200.     else{
  201.     KPPU   = tigetstr("kpp");
  202.     KPPD   = tigetstr("knp");
  203.     KPHOME = tigetstr("khome");
  204.     KU = tigetstr("kcuu1");
  205.     KD = tigetstr("kcud1");
  206.     KL = tigetstr("kcub1");
  207.     KR = tigetstr("kcuf1");
  208.     if(KU != NULL && (KL != NULL && (KR != NULL && KD != NULL))){
  209.         kpinsert(KU,K_PAD_UP);
  210.         kpinsert(KD,K_PAD_DOWN);
  211.         kpinsert(KL,K_PAD_LEFT);
  212.         kpinsert(KR,K_PAD_RIGHT);
  213.  
  214.         if(KPPU != NULL)
  215.           kpinsert(KPPU,K_PAD_PREVPAGE);
  216.         if(KPPD != NULL)
  217.           kpinsert(KPPD,K_PAD_NEXTPAGE);
  218.         if(KPHOME != NULL)
  219.           kpinsert(KPHOME,K_PAD_HOME);
  220.     }
  221.     }
  222.  
  223.     /*
  224.      * add default keypad sequences to the trie...
  225.      */
  226.     if(gmode&MDFKEY){
  227.     /*
  228.      * Initialize UW-modified NCSA telnet to use its functionkeys
  229.      */
  230.     if(Pmaster == NULL){
  231.         puts("\033[99h");
  232.     }
  233.  
  234.     /*
  235.      * this is sort of a hack [no kidding], but it allows us to use
  236.      * the function keys on pc's running telnet
  237.      */
  238.  
  239.     /* 
  240.      * UW-NDC/UCS vt10[01] application mode.
  241.      */
  242.     kpinsert("OP",F1);
  243.     kpinsert("OQ",F2);
  244.     kpinsert("OR",F3);
  245.     kpinsert("OS",F4);
  246.     kpinsert("Op",F5);
  247.     kpinsert("Oq",F6);
  248.     kpinsert("Or",F7);
  249.     kpinsert("Os",F8);
  250.     kpinsert("Ot",F9);
  251.     kpinsert("Ou",F10);
  252.     kpinsert("Ov",F11);
  253.     kpinsert("Ow",F12);
  254.  
  255.     /*
  256.      * special keypad functions
  257.      */
  258.     kpinsert("[4J",K_PAD_PREVPAGE);
  259.     kpinsert("[3J",K_PAD_NEXTPAGE);
  260.     kpinsert("[2J",K_PAD_HOME);
  261.     kpinsert("[N",K_PAD_END);
  262.  
  263.     /* 
  264.      * ANSI mode.
  265.      */
  266.     kpinsert("[=a",F1);
  267.     kpinsert("[=b",F2);
  268.     kpinsert("[=c",F3);
  269.     kpinsert("[=d",F4);
  270.     kpinsert("[=e",F5);
  271.     kpinsert("[=f",F6);
  272.     kpinsert("[=g",F7);
  273.     kpinsert("[=h",F8);
  274.     kpinsert("[=i",F9);
  275.     kpinsert("[=j",F10);
  276.     kpinsert("[=k",F11);
  277.     kpinsert("[=l",F12);
  278.  
  279.     HelpKeyNames = funckeynames;
  280.  
  281.     }
  282.     else{
  283.     HelpKeyNames = NULL;
  284.     }
  285.  
  286.     /*
  287.      * DEC vt100, ANSI and cursor key mode.
  288.      */
  289.     kpinsert("OA",K_PAD_UP);
  290.     kpinsert("OB",K_PAD_DOWN);
  291.     kpinsert("OD",K_PAD_LEFT);
  292.     kpinsert("OC",K_PAD_RIGHT);
  293.  
  294.     /*
  295.      * DEC vt100, ANSI and cursor key mode reset.
  296.      */
  297.     kpinsert("[A",K_PAD_UP);
  298.     kpinsert("[B",K_PAD_DOWN);
  299.     kpinsert("[D",K_PAD_LEFT);
  300.     kpinsert("[C",K_PAD_RIGHT);
  301.  
  302.     /*
  303.      * DEC vt52 mode.
  304.      */
  305.     kpinsert("A",K_PAD_UP);
  306.     kpinsert("B",K_PAD_DOWN);
  307.     kpinsert("D",K_PAD_LEFT);
  308.     kpinsert("C",K_PAD_RIGHT);
  309.  
  310.     /*
  311.      * Sun Console sequences.
  312.      */
  313.     kpinsert("[215z",K_PAD_UP);
  314.     kpinsert("[221z",K_PAD_DOWN);
  315.     kpinsert("[217z",K_PAD_LEFT);
  316.     kpinsert("[219z",K_PAD_RIGHT);
  317.  
  318.     if (CE == NULL)        /* will we be able to use clear to EOL? */
  319.       eolexist = FALSE;
  320.  
  321.     /* This is done ... */
  322.     initstrng = tigetstr ("is2");
  323.     /* ... on the assumption that this meant something in tcap.c */
  324.     if(initstrng && *initstrng != '\0')
  325.       puts(initstrng);
  326.  
  327.     ttopen();
  328. }
  329.  
  330.  
  331.  
  332. #define    newnode()    (struct KBSTREE *)malloc(sizeof(struct KBSTREE))
  333. /*
  334.  * kbinsert - insert a keystroke escape sequence into the global search
  335.  *          structure.
  336.  */
  337. static kpinsert(kstr, kval)
  338. char    *kstr;
  339. int    kval;
  340. {
  341.     register    char    *buf;
  342.     register    struct KBSTREE *temp;
  343.     register    struct KBSTREE *trail;
  344.  
  345.     if(kstr == NULL)
  346.       return;
  347.  
  348.     temp = trail = kpadseqs;
  349.     if(kstr[0] == '\033')
  350.       buf = kstr+1;            /* can the ^[ character */ 
  351.     else
  352.       buf = kstr;
  353.  
  354.     for(;;) {
  355.     if(temp == NULL){
  356.         temp = newnode();
  357.         temp->value = *buf;
  358.         temp->func = 0;
  359.         temp->left = NULL;
  360.         temp->down = NULL;
  361.         if(kpadseqs == NULL)
  362.           kpadseqs = temp;
  363.         else
  364.           trail->down = temp;
  365.     }
  366.     else{                /* first entry */
  367.         while((temp != NULL) && (temp->value != *buf)){
  368.         trail = temp;
  369.         temp = temp->left;
  370.         }
  371.         if(temp == NULL){   /* add new val */
  372.         temp = newnode();
  373.         temp->value = *buf;
  374.         temp->func = 0;
  375.         temp->left = NULL;
  376.         temp->down = NULL;
  377.         trail->left = temp;
  378.         }
  379.     }
  380.  
  381.     if (*(++buf) == '\0'){
  382.         break;
  383.     }
  384.     else{
  385.         trail = temp;
  386.         temp = temp->down;
  387.     }
  388.     }
  389.  
  390.     if(temp != NULL)
  391.       temp->func = kval;
  392. }
  393.  
  394.  
  395. /*
  396.  * tinfoinsert - insert a character at the current character position.
  397.  *               IC takes precedence.
  398.  */
  399. tinfoinsert(ch)
  400. register char    ch;
  401. {
  402.     if(IC != NULL){
  403.     putpad(IC);
  404.     ttputc(ch);
  405.     }
  406.     else{
  407.     putpad(IM);
  408.     ttputc(ch);
  409.     putpad(EI);
  410.     }
  411. }
  412.  
  413.  
  414. /*
  415.  * tinfodelete - delete a character at the current character position.
  416.  */
  417. tinfodelete()
  418. {
  419.     if(DM == NULL && ED == NULL)
  420.       putpad(DC);
  421.     else{
  422.     putpad(DM);
  423.     putpad(DC);
  424.     putpad(ED);
  425.     }
  426. }
  427.  
  428.  
  429. /*
  430.  * tcapscrolldn() - open a line at the given row position.
  431.  *               use either region scrolling or deleteline/insertline
  432.  *               to open a new line.
  433.  */
  434. tcapscrolldn(row, n)
  435. register int row;
  436. register int n;
  437. {
  438.     register int i;
  439.  
  440.     if(CS != NULL){
  441.     putpad(tgoto(CS, term.t_nrow - 3, row));
  442.     tinfomove(row, 0);
  443.     for(i = 0; i < n; i++)
  444.       putpad( (SR != NULL && *SR != '\0') ? SR : "\n" );
  445.     putpad(tgoto(CS, term.t_nrow, 0));
  446.     tinfomove(row, 0);
  447.     }
  448.     else{
  449.     /*
  450.      * this code causes a jiggly motion of the keymenu when scrolling
  451.      */
  452.     for(i = 0; i < n; i++){
  453.         tinfomove(term.t_nrow - 3, 0);
  454.         putpad(DL);
  455.         tinfomove(row, 0);
  456.         putpad(AL);
  457.     }
  458. #ifdef    NOWIGGLYLINES
  459.     /*
  460.      * this code causes a sweeping motion up and down the display
  461.      */
  462.     tinfomove(term.t_nrow - 2 - n, 0);
  463.     for(i = 0; i < n; i++)
  464.       putpad(DL);
  465.     tinfomove(row, 0);
  466.     for(i = 0; i < n; i++)
  467.       putpad(AL);
  468. #endif
  469.     }
  470. }
  471.  
  472.  
  473. /*
  474.  * tcapscrollup() - open a line at the given row position.
  475.  *               use either region scrolling or deleteline/insertline
  476.  *               to open a new line.
  477.  */
  478. tcapscrollup(row, n)
  479. register int row;
  480. register int n;
  481. {
  482.     register int i;
  483.  
  484.     if(CS != NULL){
  485.     putpad(tgoto(CS, term.t_nrow - 3, row));
  486.     /* setting scrolling region moves cursor to home */
  487.     tinfomove(term.t_nrow-3, 0);
  488.     for(i = 0;i < n; i++)
  489.       putpad((SF == NULL || SF[0] == '\0') ? "\n" : SF);
  490.     putpad(tgoto(CS, term.t_nrow, 0));
  491.     tinfomove(2, 0);
  492.     }
  493.     else{
  494.     for(i = 0; i < n; i++){
  495.         tinfomove(row, 0);
  496.         putpad(DL);
  497.         tinfomove(term.t_nrow - 3, 0);
  498.         putpad(AL);
  499.     }
  500. #ifdef  NOWIGGLYLINES
  501.     /* see note above */
  502.     tinfomove(row, 0);
  503.     for(i = 0; i < n; i++)
  504.       putpad(DL);
  505.     tinfomove(term.t_nrow - 2 - n, 0);
  506.     for(i = 0;i < n; i++)
  507.       putpad(AL);
  508. #endif
  509.     }
  510. }
  511.  
  512.  
  513.  
  514. /*
  515.  * o_insert - use terminfo to optimized character insert
  516.  *            returns: true if it optimized output, false otherwise
  517.  */
  518. o_insert(c)
  519. char c;
  520. {
  521.     if(inschar){
  522.     tinfoinsert(c);
  523.     return(1);            /* no problems! */
  524.     }
  525.  
  526.     return(0);                /* can't do it. */
  527. }
  528.  
  529.  
  530. /*
  531.  * o_delete - use terminfo to optimized character insert
  532.  *            returns true if it optimized output, false otherwise
  533.  */
  534. o_delete()
  535. {
  536.     if(delchar){
  537.     tinfodelete();
  538.     return(1);            /* deleted, no problem! */
  539.     }
  540.  
  541.     return(0);                /* no dice. */
  542. }
  543.  
  544.  
  545. /*
  546.  * scrollup - use terminal characteristics to optimize screen updates that
  547.  *            scroll up the display
  548.  */
  549. o_scrollup()
  550. {
  551. }
  552.  
  553.  
  554. /*
  555.  * scrolldown - use terminal characteristics to optimize screen updates that
  556.  *              scroll down the display
  557.  */
  558. o_scrolldown()
  559. {
  560. }
  561.  
  562.  
  563. static tinfomove(row, col)
  564. register int row, col;
  565. {
  566.     putpad(tgoto(CM, col, row));
  567. }
  568.  
  569.  
  570. static tinfoeeol()
  571. {
  572.     putpad(CE);
  573. }
  574.  
  575.  
  576. static tinfoeeop()
  577. {
  578.         putpad(CL);
  579. }
  580.  
  581.  
  582. static tinforev(state)        /* change reverse video status */
  583. int state;                    /* FALSE = normal video, TRUE = rev video */
  584. {
  585.     if (state) {
  586.     if (SO != NULL)
  587.       putpad(SO);
  588.     } else {
  589.     if (SE != NULL)
  590.       putpad(SE);
  591.     }
  592. }
  593.  
  594.  
  595. static tinfobeep()
  596. {
  597.     ttputc(BEL);
  598. }
  599.  
  600.  
  601. static putpad(str)
  602. char    *str;
  603. {
  604.     tputs(str, 1, ttputc);
  605. }
  606.  
  607.  
  608. static putnpad(str, n)
  609. char    *str;
  610. {
  611.     tputs(str, n, ttputc);
  612. }
  613.